package com.epam.weblibrary.service.order;

import com.epam.weblibrary.entities.book.Book;
import com.epam.weblibrary.entities.order.Order;
import com.epam.weblibrary.entities.user.User;
import com.epam.weblibrary.repositories.book.BookRepository;
import com.epam.weblibrary.repositories.order.OrderRepository;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.SneakyThrows;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.List;

/**
 * Created by Iurii_Miedviediev on 9/17/2014.
 */
@Service
@Transactional(readOnly = true)
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderRepository orderRepository;

    @Autowired
    BookRepository bookRepository;

    @Override
    public List<Order> findAll() {
        return orderRepository.findAll();
    }

    @Override
    public List<Order> findByUser(User user) {
        return orderRepository.findByUser(user);
    }

    @Override
    public Order createOrder(List<Book> cart, User user) {
        Order order = new Order(cart, new Date(), user);

        for(Book book : order.getItems()) {
            book.setAvailable(false);
            bookRepository.saveAndFlush(book);
        }

        order.setQrcode(QRCode.from("http://localhost:8080/order/" + order.getId())
                .to(ImageType.PNG).withSize(300, 300).stream().toByteArray());
        orderRepository.saveAndFlush(order);
        return order;
    }

    @Override
    public Order find(Long id) {
        return orderRepository.findOne(id);
    }

    @Override
    @SneakyThrows
    public byte[] createQrPdfDocument(Long id) {

        //configure document to convert it then to byte array
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Document doc = new Document(PageSize.A4);
        PdfWriter.getInstance(doc, byteArrayOutputStream);
        doc.open();
        createPDF(doc, id);
        doc.close();

        return byteArrayOutputStream.toByteArray();
    }

    private void createPDF(Document doc, Long id) throws DocumentException, IOException {
        Order order = orderRepository.findOne(id);
        byte[] qrCode = order.getQrcode();

        Image background = Image.getInstance("src/main/webapp/resources/img/epam-letter.png");
        background.scaleAbsolute(PageSize.A4);
        background.setAbsolutePosition(0, 0);
        doc.add(background);

        Paragraph title = new Paragraph("Web-Library Order #" + order.getId());
        title.setSpacingBefore(100.0f);
        title.setAlignment(Element.ALIGN_CENTER);
        doc.add(title);

        //table with books from the order
        PdfPTable table = new PdfPTable(4);
        table.setWidthPercentage(100.0f);
        table.setWidths(new float[] {3.0f, 2.0f, 2.0f, 2.0f});
        table.setSpacingBefore(10);

        // define font for table header row
        Font font = FontFactory.getFont(FontFactory.HELVETICA);
        font.setColor(BaseColor.WHITE);

        // define table header cell
        PdfPCell cell = new PdfPCell();
        cell.setBackgroundColor(new BaseColor(0,44,120));
        cell.setPadding(5);

        // write table header
        cell.setPhrase(new Phrase("Book Title", font));
        table.addCell(cell);

        cell.setPhrase(new Phrase("Author", font));
        table.addCell(cell);

        cell.setPhrase(new Phrase("Year", font));
        table.addCell(cell);

        cell.setPhrase(new Phrase("Price", font));
        table.addCell(cell);

        Long totalPrice = 0L;
        // write table row data
        for (Book book : order.getItems()) {
            table.addCell(book.getTitle());
            table.addCell(book.getAuthor());
            table.addCell(book.getYear().toString());
            table.addCell("$" + ((Double) (book.getPrice() / 100.0)).toString());
            totalPrice += book.getPrice();
        }

        doc.add(table);

        Paragraph total = new Paragraph("Total price is: $" + totalPrice/100.0);
        total.setAlignment(Element.ALIGN_RIGHT);
        doc.add(total);

        String login = order.getUser().getLogin();
        Paragraph message = new Paragraph("Dear " + login + ", please, print this document and show it to the librarian to receive your order.");
        message.setSpacingBefore(30.0f);
        doc.add(message);

        Image image = Image.getInstance(qrCode);
        image.setAlignment(Image.ALIGN_CENTER);
        doc.add(image);
    }
}
